feat(geocoder): derive geocoderProvider from Poracle's remote config - #1244
Conversation
|
The new fallback can pair Poracle's provider type with a different locally configured URL, regressing valid existing Nominatim configurations when Poracle uses Photon. Review comment:
|
|
Correct, and this was a regression I introduced rather than a gap. Fixed in 98298a0. The fallback was unconditional, so a webhook with a local The backend type is now inherited only when the URL was inherited with it. A URL and the protocol used to talk to it are one setting in two fields, and splitting them across two sources cannot produce a working pair except by luck. An explicit local
Three cases cover it: inheriting when the URL came from Poracle, refusing to inherit when it did not, and local config winning regardless. Confirmed failing without the guard (34/35) rather than assumed. The irony is not lost on me. This PR exists to fix an asymmetry in how the pair is populated, and it shipped by breaking the pairing in the other direction. The branch is rebased on the updated #1243, which now also carries the reverse-shape fix from your other review. 🤖 Addressed by Claude Code |
5085e19 to
98298a0
Compare
Mygod
left a comment
There was a problem hiding this comment.
The revised logic keeps the inherited provider paired with Poracle's URL while preserving explicit local configuration. Focused tests, lint, formatting, and the production build passed with no actionable regression found.
a7dd909 to
d3f1414
Compare
nominatimUrl already falls back to Poracle's providerURL, so a deployment can get its geocoder URL from Poracle without restating it here. The backend type had no such fallback, which left half the pair auto-populating and the other half not: an operator whose URL came from Poracle still had to hand-set geocoderProvider locally, or every request silently took the Nominatim branch. PoracleNG now reports the backend behind providerURL as `provider`, so geocoderProvider follows the same rule as its URL. Local config still wins, matching how providerURL and addressFormat already behave. Poracle also offers google and none. Neither has a ReactMap equivalent, so they resolve to undefined rather than being mapped onto nominatim, which would claim something untrue about the backend. The match is exact, so a differently-cased value is ignored rather than guessed at. `provider` is destructured out of remoteConfig whether or not it is usable. this.provider is the *webhook* provider, an unrelated field that happens to share the name, and letting Poracle's value through Object.assign(this, rest) would silently overwrite it. The resolution is a small exported function because #fetchConfig is private and would otherwise need a stubbed HTTP round trip to reach. Four tests cover the derivation, local precedence, the ignored backends, and the webhook provider surviving a remote payload that carries a geocoding provider.
The fallback was unconditional, so a webhook with a local nominatimUrl and no
geocoderProvider inherited Photon from a Photon-backed Poracle while keeping its
own Nominatim URL. That is the default shape of every existing Nominatim
deployment, and it made searches and reverse lookups return {} against an
endpoint that had been working.
A URL and the protocol used to talk to it are one setting in two fields, and
splitting them across two sources cannot produce a working pair by accident.
The backend type is now inherited only when the URL was inherited with it.
An explicit local geocoderProvider still wins in either case, which is the only
way to run a backend Poracle does not report.
resolveGeocoderProvider takes a named argument object rather than a third
positional boolean, so the pairing rule is legible at the call site.
d3f1414 to
b647126
Compare
|
🎉 This PR is included in version 1.51.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Stacked on #1243. Base is
fix/geocoder-photon-misconfigso the shared test file does not conflict; retarget tomainonce that merges.Requires the PoracleNG side, which adds
providerto the/api/config/poracleWebpayload.The asymmetry this removes
nominatimUrlalready falls back to Poracle'sproviderURL, so a deployment can take its geocoder URL from Poracle and never mention it in ReactMap's config. The backend type had no such fallback:Half the pair auto-populated and the other half did not. An operator whose URL came from Poracle still had to hand-set
geocoderProviderlocally, and if they did not, every request silently took the Nominatim branch against a Photon URL. That is not a hypothetical: it is what took a production instance down after #1242 shipped.PoracleNG now reports the backend behind
providerURLasprovider, sogeocoderProvidercan follow the same rule as its URL. Local config still wins, matching howproviderURLandaddressFormatalready behave.Ignored backends
Poracle also offers
googleandnone. Neither has a ReactMap equivalent, so they resolve toundefinedrather than being mapped ontonominatim, which would claim something untrue about the backend. The match is exact, so a differently-cased value is ignored rather than guessed at.The name collision
provideris destructured out ofremoteConfigwhether or not it is usable:this.provideris the webhook provider, set fromwebhook.providerin the constructor. It is an unrelated field that happens to share a name with Poracle's geocoding provider, and letting the remote value through the spread would silently overwrite it. It is currently read nowhere else in ReactMap, so this would have been invisible until something started reading it.Testing
The resolution lives in a small exported function because
#fetchConfigis private and would otherwise need a stubbed HTTP round trip to reach.Four cases: the derivation, local precedence over the remote value, the ignored backends, and the webhook provider surviving a remote payload that carries a geocoding provider.
yarn lintpassesyarn buildpassesyarn prettierpassesnode --test server/test/geocoder.test.jspasses 30/30Not exercised against a live Poracle. The payload shape is taken from PoracleNG's
poracleWebResponsestruct and its OpenAPI golden, not from a real response, so the field name is worth confirming against a running instance before merge.yarn testalso runsserver/test/rocketPokemonFiltering.test.js, which fails withNo database selected for React Map Tables. Unrelated and predates this branch:server/src/db/knexfile.cjscallsprocess.exit(9)at import when no schema hasuserin itsuseFor.